package com.changyue.bleHelper;

import android.Manifest;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;

import com.changyue.activity.basic.BasicActivity;
import com.changyue.activity.me.adapter.DeviceListAdapter;
import com.changyue.bleLib.BleRssiDevice;
import com.changyue.blood.databinding.ActivityScanBinding;
import com.changyue.ui.HeadView;
import com.changyue.util.CustomToast;

import org.greenrobot.eventbus.EventBus;

import java.util.LinkedList;
import java.util.List;
import java.util.UUID;

import cn.com.heaton.blelibrary.ble.Ble;
import cn.com.heaton.blelibrary.ble.BleLog;
import cn.com.heaton.blelibrary.ble.callback.BleConnectCallback;
import cn.com.heaton.blelibrary.ble.callback.BleNotifyCallback;
import cn.com.heaton.blelibrary.ble.callback.BleScanCallback;
import cn.com.heaton.blelibrary.ble.callback.BleStatusCallback;
import cn.com.heaton.blelibrary.ble.model.BleDevice;
import cn.com.heaton.blelibrary.ble.model.ScanRecord;
import cn.com.heaton.blelibrary.ble.utils.ByteUtils;
import cn.com.heaton.blelibrary.ble.utils.Utils;

public class ScanActivity extends BasicActivity {
    private String TAG = ScanActivity.class.getSimpleName();

    public static final int REQUEST_GPS = 4;

    ActivityScanBinding binding;

    private DeviceListAdapter adapter = null;

    private List<BleRssiDevice> bleRssiDevices = new LinkedList<>();
    private Ble<BleRssiDevice> ble = Ble.getInstance();
    private Ble<BleDevice> bleManager = Ble.getInstance();

    public static void start(Context context) {
        Intent intent = new Intent(context, ScanActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        binding = ActivityScanBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        binding.headView.setRightTxt("刷新");
        binding.headView.setRightTxtVisibility(true);
        binding.headView.setOnRightClickListener(new HeadView.OnRightClickListener() {
            @Override
            public void onRightClickListener(View view) {
                bleRssiDevices.clear();
                adapter.notifyDataSetChanged();
            }
        });

        bleRssiDevices = new LinkedList<>();
        adapter = new DeviceListAdapter(this, bleRssiDevices);
        binding.deviceList.setAdapter(adapter);

        binding.deviceList.setClickable(true);
        binding.deviceList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                onDeviceClick(position);
            }
        });

        initBleStatus();
        (new Handler()).postDelayed(new Runnable() {
            @Override
            public void run() {
                checkPermission();
            }
        }, 1000);
    }

    //监听蓝牙开关状态
    private void initBleStatus() {
        ble.setBleStatusCallback(new BleStatusCallback() {
            @Override
            public void onBluetoothStatusChanged(boolean isOn) {
                BleLog.i(TAG, "onBluetoothStatusOn: 蓝牙是否打开>>>>:" + isOn);
                CustomToast.middleBottom(ScanActivity.this, isOn ? "蓝牙开启" : "蓝牙未开启");
                if (isOn) {
                    checkGpsStatus();
                } else {
                    if (ble.isScanning()) {
                        ble.stopScan();
                    }
                }
            }
        });
    }

    public void checkPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
                    checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
                    checkSelfPermission(Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED ||
                    checkSelfPermission(Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED ||
                    checkSelfPermission(Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
                // Permission is not granted
                requestPermissions(new String[]{
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.BLUETOOTH,
                        Manifest.permission.BLUETOOTH_CONNECT,
                        Manifest.permission.BLUETOOTH_SCAN
                }, 0);
                return;
            } else {
                checkBlueStatus();
            }
        } else {
            if (checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
                    checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
                    checkSelfPermission(Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED) {
                // Permission is not granted
                requestPermissions(new String[]{
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.BLUETOOTH
                }, 0);
                return;
            } else {
                checkBlueStatus();
            }
        }
    }

    private void checkBlueStatus() {
        if (!ble.isSupportBle(this)) {
            CustomToast.middleBottom(ScanActivity.this, "蓝牙不支持");
            finish();
        }
        if (!ble.isBleEnable()) {
            CustomToast.middleBottom(ScanActivity.this, "蓝牙未开启");
        } else {
            checkGpsStatus();
        }
    }

    private void checkGpsStatus() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
                && !Utils.isGpsOpen(ScanActivity.this)) {
            new AlertDialog.Builder(ScanActivity.this)
                    .setTitle("提示")
                    .setMessage("为了更精确的扫描到Bluetooth LE设备,请打开GPS定位")
                    .setPositiveButton("确定", (dialog, which) -> {
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivityForResult(intent, REQUEST_GPS);
                    })
                    .setNegativeButton("取消", null)
                    .create()
                    .show();
            return;
        }

        ble.startScan(scanCallback);
    }

    private BleScanCallback<BleRssiDevice> scanCallback = new BleScanCallback<BleRssiDevice>() {
        @Override
        public void onLeScan(final BleRssiDevice device, int rssi, byte[] scanRecord) {
            synchronized (ble.getLocker()) {
                for (int i = 0; i < bleRssiDevices.size(); i++) {
                    BleRssiDevice rssiDevice = bleRssiDevices.get(i);
                    if (TextUtils.equals(rssiDevice.getBleAddress(), device.getBleAddress())) {
                        if (rssiDevice.getRssi() != rssi && System.currentTimeMillis() - rssiDevice.getRssiUpdateTime() > 1000L) {
                            rssiDevice.setRssiUpdateTime(System.currentTimeMillis());
                            rssiDevice.setRssi(rssi);
                            notifyDataSetChanged();
                        }
                        return;
                    }
                }
                device.setScanRecord(ScanRecord.parseFromBytes(scanRecord));
                device.setRssi(rssi);
                bleRssiDevices.add(device);
                adapter.notifyDataSetChanged();
            }
        }
    };

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Boolean isAllGrant = true;
        for (int grant : grantResults) {
            if (grant != PackageManager.PERMISSION_GRANTED) {
                isAllGrant = false;
                break;
            }
        }
        if (!isAllGrant) {
            CustomToast.middleBottom(ScanActivity.this, "请授权全部的权限");
            return;
        }

        ble.startScan(scanCallback);
    }

    void notifyDataSetChanged() {
        adapter.notifyDataSetChanged();
        if (bleRssiDevices.size() > 0) {
            binding.noDevice.setVisibility(View.GONE);
        } else {
            binding.noDevice.setVisibility(View.VISIBLE);
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    public void onDeviceClick(final int pos) {
        if (bleManager.isScanning()) {
            bleManager.stopScan();
        }
        BleRssiDevice bleDeviceInfo = bleRssiDevices.get(pos);
        bleManager.connect(bleDeviceInfo, connectCallback);
    }

    private BleConnectCallback<BleDevice> connectCallback = new BleConnectCallback<BleDevice>() {
        @Override
        public void onConnectionChanged(BleDevice device) {
            Log.e(TAG, "onConnectionChanged: " + device.getConnectionState() + Thread.currentThread().getName());
            if (device.isConnected()) {
                binding.headView.setTitle("已连接");
            } else if (device.isConnecting()) {
                binding.headView.setTitle("连接中...");
            } else if (device.isDisconnected()) {
                binding.headView.setTitle("未连接");
            }
        }

        @Override
        public void onConnectFailed(BleDevice device, int errorCode) {
            super.onConnectFailed(device, errorCode);
            CustomToast.middleBottom(ScanActivity.this, "连接异常，异常状态码:" + errorCode);
        }

        @Override
        public void onConnectCancel(BleDevice device) {
            super.onConnectCancel(device);
            Log.e(TAG, "onConnectCancel: " + device.getBleName());
            CustomToast.middleBottom(ScanActivity.this, "连接取消");
        }

        @Override
        public void onServicesDiscovered(BleDevice device, BluetoothGatt gatt) {
            super.onServicesDiscovered(device, gatt);

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
//                    gattServices.addAll(gatt.getServices());
                    adapter.notifyDataSetChanged();
                }
            });

        }
        @Override
        public void onReady(BleDevice device) {
            super.onReady(device);
            //连接成功后，设置通知
            bleManager.enableNotify(device, true, new BleNotifyCallback<BleDevice>() {
                @Override
                public void onChanged(BleDevice device, BluetoothGattCharacteristic characteristic) {
                    UUID uuid = characteristic.getUuid();
                    BleLog.e(TAG, "onChanged==uuid:" + uuid.toString());
                    BleLog.e(TAG, "onChanged==data:" + ByteUtils.toHexString(characteristic.getValue()));
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            String content = String.format("收到设备通知数据: %s", ByteUtils.toHexString(characteristic.getValue()));
                        }
                    });
                }

                @Override
                public void onNotifySuccess(BleDevice device) {
                    super.onNotifySuccess(device);
                    BleLog.e(TAG, "onNotifySuccess: "+device.getBleName());
                    EventBus.getDefault().post(ScanActivity.class.getName());
                    finish();
                }
            });
        }
    };
}
